home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-11 | 10.0 KB | 515 lines | [TEXT/MMCC] |
- //==================================================================
- // MacWT.c <tur 01-May-94>
- //
- // Mac interface to Chris Laurel's 'wt' demo ["what's that"].
- //
- // Comments, Bug Reports/Fixes, etc, to turly@isltd.insignia.com
- //
- //==================================================================
-
- #ifndef __QUICKDRAW__
- #include "LoadMacHeaders.h"
- #endif /* __QUICKDRAW__ */
-
- #include <stdio.h>
- #include <string.h>
-
- #include "Failure.h"
- #include "DirScrnWrite.h"
- #include "wt.h" /* wt */
- #include "error.h"
- #include "input.h"
- #include "framebuf.h"
- #include "graphics.h"
- #include "MacGame.h"
-
-
- /**/
-
-
- PixMap gOffscreenPixMap;
- WindowPtr gWTFTWindow;
-
-
- /**/
-
-
- static long gStartTicks, gFrameCount;
- static Intent gIntent;
-
-
- /**/
-
-
- void init_input_devices(void)
- {
- memset(&gIntent, 0, sizeof(gIntent));
- }
-
-
- void end_input_devices(void)
- {
- // nada for Mac
- }
-
-
- /**/
-
-
- static unsigned CorrectPCRGB(unsigned rgbVal)
- {
- register unsigned long v = rgbVal;
-
- // The PC RGB Values are somewhat low for my liking.
- // This little hack corrects them...
-
- if (v) {
- if (v < 0x0C0C)
- v = 0x0C0C;
- else
- if (v+v < 0xFFFF)
- v += v;
- else
- if (v < 0xEEEE)
- v += 0x1000;
- }
-
- return v;
- }
-
-
- /**/
-
-
- int LoadPaletteFromFile(PaletteHandle pal, const char *palFile)
- {
- FILE *fp;
- int i, r, g, b;
- RGBColor col;
- char name[256];
-
- if (!palFile)
- palFile = DEFAULT_PALETTE_FILE;
-
- fp = fopen(palFile, "rb");
-
- if (fp == NULL) {
- // couldn't open it -- try the ":wt:" subdirectory...
-
- sprintf(name, ":wt:%s", palFile);
- fp = fopen(name, "rb");
- if (fp == NULL)
- Fail("unable to open palette file '%s'", palFile);
- }
-
- col.red = col.green = col.blue = 0xFFFF; // white, but also transparent!
- SetEntryColor(pal, 0, &col);
-
- for (i = 1; i <= PALETTE_ENTRIES; i++) {
- r = getc(fp);
- g = getc(fp);
- b = getc(fp);
- if (b == EOF)
- Fail("error reading palette file '%s'", palFile);
-
- col.red = (r << 8) | r;
- col.green = (g << 8) | g;
- col.blue = (b << 8) | b;
-
- col.red = CorrectPCRGB(col.red);
- col.green = CorrectPCRGB(col.green);
- col.blue = CorrectPCRGB(col.blue);
-
- SetEntryColor(pal, i, &col);
- }
- fclose(fp);
-
- // set all others (as yet unassigned) to black!
-
- col.red = col.green = col.blue = 0;
- while (i < 255) {
- SetEntryColor(pal, i, &col);
- ++i;
- }
-
- return PALETTE_ENTRIES+2;
- }
-
-
- /**/
-
- // Mac palette indices are PC indices + 1
- // due to QuickDraw requirement that white be index 0
- // and black index 255 -- PCs are generally the other way round...
-
- void MacFixupPixelData(unsigned char *buf, int nBytes)
- {
- while (nBytes--) {
- *buf += 1;
- ++buf;
- }
- }
-
-
- /**/
-
-
- void init_graphics(void)
- {
-
- // Screen width must be multiple of 4...
-
- FailIf(SCREEN_WIDTH & 3);
-
- if (!gOffscreenPixMap.baseAddr) {
- gOffscreenPixMap.baseAddr = NewPtr(SCREEN_HEIGHT * SCREEN_WIDTH);
- FailNil(gOffscreenPixMap.baseAddr);
-
- gOffscreenPixMap.rowBytes = 0x8000 | SCREEN_WIDTH;
- SetRect(&gOffscreenPixMap.bounds, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-
- gOffscreenPixMap.pixelSize = 8;
- gOffscreenPixMap.cmpCount = 1;
- gOffscreenPixMap.cmpSize = 8;
- gOffscreenPixMap.pmTable = gDirClut;
- }
- }
-
-
- /**/
-
-
- void end_graphics(void)
- {
- }
-
-
- /**/
-
-
- static void ShowIfPaused(void)
- {
- int oldFace, oldSize, oldFont, oldMode;
- long tix;
- static int doWhite = true;
- static long lastFlashTickCount;
-
- if (gPaused) {
-
- oldFace = gWTFTWindow->txFace;
- oldFont = gWTFTWindow->txFont;
- oldSize = gWTFTWindow->txSize;
- oldMode = gWTFTWindow->txMode;
-
- tix = TickCount();
- if (!lastFlashTickCount)
- lastFlashTickCount = tix;
- ForeColor((doWhite) ? whiteColor : blackColor);
- if (tix - lastFlashTickCount > 30) {
- lastFlashTickCount = tix;
- doWhite = !doWhite;
- }
- MoveTo(6, gWTFTWindow->portRect.top + 30);
- TextFont(times);
- TextFace(bold);
- TextSize(24);
- TextMode(srcOr);
-
- DrawString((StringPtr)"\pPaused");
-
- TextSize(12);
- DrawString((StringPtr)"\p - press TAB to continue");
-
- TextSize(oldSize);
- TextFace(oldFace);
- TextFont(oldFont);
- TextMode(oldMode);
-
- ForeColor(blackColor);
- }
- }
-
-
- /**/
-
-
- static void MacAttractMode(void)
- {
- int oldFont, oldSize, oldFace, oldMode;
-
- FailNil(gWTFTWindow);
-
- // This is a bit of a hack, I’m afraid...
-
- if (!gGameOn) {
- SetPort(gWTFTWindow);
-
- oldFont = gWTFTWindow->txFont;
- oldSize = gWTFTWindow->txSize;
- oldFace = gWTFTWindow->txFace;
- oldMode = gWTFTWindow->txMode;
-
- TextFont(geneva);
- TextSize(9);
- TextMode(srcOr);
-
- MoveTo(4, gWTFTWindow->portRect.bottom - kBottomBorder + 10);
- TextFace(bold);
- DrawString((StringPtr)"\pwt ");
- DrawString(gWTVersion);
- DrawString((StringPtr)"\p - chris laurel’s portable 3D game engine ");
- #if __powerc
- DrawString((StringPtr)"\p(PPC)");
- #else
- DrawString((StringPtr)"\p(68K)");
- #endif
- MoveTo(4, gWTFTWindow->portRect.bottom - kBottomBorder + 21);
- TextFace(normal);
- DrawString((StringPtr)"\pWorld File — ");
- DrawText(gWorldFileName, 0, strlen(gWorldFileName));
- MoveTo(4, gWTFTWindow->portRect.bottom - kBottomBorder + 32);
- TextFace(italic);
- DrawString((StringPtr)"\pTo change world files, hold down SHIFT while launching MacWT");
-
- TextFont(oldFont);
- TextSize(oldSize);
- TextFace(oldFace);
- TextMode(oldMode);
- }
- }
-
-
- /**/
-
-
- void BeginGame(void)
- {
- Rect r;
-
- FailNil(gWTFTWindow);
- r = gWTFTWindow->portRect;
- r.top = r.bottom - kBottomBorder;
- EraseRect(&r);
-
- gGameOn = true;
- if (gPaused)
- TogglePause();
- }
-
-
- /**/
-
-
- void RefreshWTWindow(void)
- {
- PCopyPixFunc cpF = DirCopyPix;
- long tNow;
- char aStr[256];
- int dirWrite, dubble;
-
- FailNil(gWTFTWindow);
-
- if (gOffscreenPixMap.baseAddr) {
-
- // Dammit, I knew I forgot to extract something from TDirScrn!
- // The following was pointed out by Al Evans (al@crucible.powertools.com)
- // if we can write directly to the screen, set the ctSeed
- // to be the same as the device’s (this is for when we DON’T
- // write directly to the screen, but it does speed up _CopyBits
- // to match my (admittedly C) direct screen write code.
- // Scaling up to 640x400 (from 320x200) is still nearly 2x faster
- // with direct screen writing, though. (As you'd expect, really.)
- // Thanks Al!
-
- dirWrite = CanWriteDirectToScreen(gWTFTWindow);
- if (dirWrite) {
- (**gOffscreenPixMap.pmTable).ctSeed = (**(**(**gTheScreenDevice).gdPMap).pmTable).ctSeed;
- }
-
- dubble = rectWidth(&gWTFTWindow->portRect) >= (SCREEN_WIDTH*2);
- if (dubble)
- cpF = DirCopyPixScaled2;
-
- // We now only bother to use direct screen writes when
- // we're scan-line doubling.
-
- if (dirWrite && !gUseQuickDraw && gGameOn && dubble) {
-
- cpF((long *)gOffscreenPixMap.baseAddr, /*srcPixels*/
- SCREEN_WIDTH, /*srcRowBytes*/
- SCREEN_WIDTH, /*srcWid*/
- SCREEN_HEIGHT, /*srcHeight*/
- 0, 0, /*winStartX/Y*/
- nil); /*pixMungeFunc*/
- }
- else {
- Rect dstRect;
-
- dstRect = gWTFTWindow->portRect;
- dstRect.bottom -= kBottomBorder;
-
- CopyBits((BitMap *)&gOffscreenPixMap, &gWTFTWindow->portBits,
- &gOffscreenPixMap.bounds, &dstRect, srcCopy, nil);
-
- }
- }
-
- ShowIfPaused();
-
- MoveTo(4, gWTFTWindow->portRect.bottom - kBottomBorder + 20);
-
- if (gGameOn && gShowFPS) {
- tNow = (TickCount() - gStartTicks) / 60;
- if (!tNow)
- tNow = 1;
-
- aStr[0] = sprintf(aStr+1, "Frame: %ld, fps %ld ", gFrameCount, ((unsigned long)gFrameCount)/tNow);
- DrawString((StringPtr)aStr);
- }
-
- }
-
- /**/
-
-
- void update_screen(Framebuffer *fb)
- {
- RefreshWTWindow();
-
- if (gGameOn) {
- ++gFrameCount;
- if (!gStartTicks)
- gStartTicks = TickCount();
- }
- }
-
-
- /**/
-
-
- Pixel *get_framebuffer_memory(int width, int height)
- {
- return (Pixel *)gOffscreenPixMap.baseAddr;
- }
-
-
- /*****/
-
-
- static void add_special(Intent *intent, int special)
- {
- if (intent->n_special < MAX_SPECIAL_INTENTIONS) {
- intent->special[intent->n_special] = special;
- intent->n_special++;
- }
- }
-
-
- /**/
-
- #define MacKeyDown(kmp, code) ((kmp[code>>3] >> (code & 7)) & 1)
-
- Intent *read_input_devices(void)
- {
- unsigned char kmp[16];
- Boolean rotating_cw,
- rotating_ccw,
- moving_forward,
- moving_backward,
- running,
- strafing;
- struct {
- int rightArrow,
- leftArrow,
- upArrow,
- downArrow,
- control,
- escape,
- shift,
- slash,
- space,
- tabKey;
- } keyboard;
-
-
- gIntent.force_x = gIntent.force_y = gIntent.force_z = 0.0;
- gIntent.force_rotate = 0.0;
- gIntent.n_special = 0;
-
- do {
- GetAndProcessEvent();
-
- GetKeys((long *)kmp);
-
- if (gPaused) {
- gStartTicks = gFrameCount = 0;
- ShowIfPaused();
- init_input_devices(); // zero out the "intent" structure...
- }
-
- if (!gGameOn) {
- // if the forward key is pressed, start the game immediately!
- if (MacKeyDown(kmp, 0x7e) || MacKeyDown(kmp, 0x5b))
- BeginGame();
- else
- MacAttractMode();
- }
-
- } while (!gGameOn || (gPaused && !gDone));
-
-
- keyboard.rightArrow = MacKeyDown(kmp, 0x7C) || MacKeyDown(kmp, 0x58);
- keyboard.leftArrow = MacKeyDown(kmp, 0x7b) || MacKeyDown(kmp, 0x56);
- keyboard.upArrow = MacKeyDown(kmp, 0x7e) || MacKeyDown(kmp, 0x5b);
- keyboard.downArrow = MacKeyDown(kmp, 0x7d) || MacKeyDown(kmp, 0x54);
- keyboard.control = MacKeyDown(kmp, 0x3b) || MacKeyDown(kmp, 0x37); // Ctrl or Cmd
- keyboard.shift = MacKeyDown(kmp, 0x38) || MacKeyDown(kmp, 0x3c);
- keyboard.slash = MacKeyDown(kmp, 0x2c) || MacKeyDown(kmp, 0x4b);
- keyboard.space = MacKeyDown(kmp, 0x31);
- keyboard.tabKey = MacKeyDown(kmp, 0x30);
- keyboard.escape = MacKeyDown(kmp, 0x35) || MacKeyDown(kmp, 0x32);
-
-
- // logic snarfed from the original "x11input.c"
-
- rotating_ccw = keyboard.leftArrow;
- rotating_cw = keyboard.rightArrow;
- moving_forward = keyboard.upArrow;
- moving_backward = keyboard.downArrow;
- running = keyboard.shift;
- strafing = keyboard.slash || keyboard.control;
-
- if (keyboard.space)
- add_special(&gIntent, INTENT_JUMP);
-
- if (gDone)
- add_special(&gIntent, INTENT_END_GAME);
-
-
- if (rotating_cw) {
- if (strafing)
- gIntent.force_y -= 0.5;
- else
- gIntent.force_rotate -= 0.5;
- }
- if (rotating_ccw) {
- if (strafing) {
- gIntent.force_y += 0.5;
- } else
- gIntent.force_rotate += 0.5;
- }
- if (moving_forward)
- gIntent.force_x += 0.5;
- if (moving_backward)
- gIntent.force_x -= 0.5;
- if (running) {
- gIntent.force_x *= 2.0;
- gIntent.force_y *= 2.0;
- gIntent.force_z *= 2.0;
- gIntent.force_rotate *= 2.0;
- }
-
- return &gIntent;
- }
-
-